(() => {
  // ----- webapi 第一天 setInterval和clearInterval案例 加类型重写 -----
  /**
   * setInterval和clearInterval案例
   */

  // 案例1：动态倒计时
  /**
   * 显示倒计时
   * document.getElementById('countdown').innerText = `活动结束剩余时间：${distance / 1000} 秒`;
   * 直接如上会报错，因为document.getElementById('countdown')可能是个null值，因此需要if判断一下
   */
  // 倒计时结束时间
  const endTime = new Date('2024-08-15T23:59:59').getTime();

  // 倒计时函数
  function countdown(): void {
    const now = new Date().getTime();
    const distance: number = endTime - now;

    // 获取倒计时元素
    const countdownElement = document.getElementById('countdown');

    // 检查元素是否存在
    if (countdownElement) {
      // 倒计时显示
      countdownElement.innerText = `活动结束剩余时间：${distance / 1000} 秒`;
    } else {
      console.log('倒计时元素不存在');
    }

    // 检查倒计时是否结束
    if (distance < 0) {
      clearInterval(intervalId);
      if (countdownElement) {
        countdownElement.innerText = '活动已结束';
      }
    }
  }

  // 设置定时器
  const intervalId = setInterval(countdown, 1000);

  // 案例2：实时更新股票价格
  // 假设这是获取股票价格的函数
  function fetchStockPrice(): void {
    // 这里应该是异步请求获取股票价格的代码
    console.log('股票价格已更新');
  }

  // 设置定时器，每60秒更新一次股票价格
  const stockUpdateInterval = setInterval(fetchStockPrice, 60000);

  // 当用户关闭股票价格更新功能时，清除定时器
  const stopUpdatesButton = document.getElementById('stopUpdates');
  if (stopUpdatesButton) {
    stopUpdatesButton.addEventListener('click', () => {
      clearInterval(stockUpdateInterval);
      console.log('股票价格更新已停止');
    });
  } else {
    console.log('停止股票价格更新按钮不存在');
  }

  /**
   * setTimeout和clearTimeout
   */
  // 案例1：登录表单的防抖（Debouncing）
  /**
   * setTimeout的类型定义：NodeJS.Timeout
   */
  // 存储setTimeout的变量
  let timeoutId: NodeJS.Timeout;

  // 用户输入时调用的函数
  function onUsernameInput(): void {
    // 如果已经有一个setTimeout在运行，先清除它
    if (timeoutId) {
      clearTimeout(timeoutId);
    }

    // 设置一个新的setTimeout，300ms后执行验证用户名的函数
    timeoutId = setTimeout(() => {
      console.log('验证用户名...');
      // 实际应用中，这里可以是发送请求到服务器验证用户名的代码
    }, 300);
  }

  // 绑定输入事件
  const usernameInput = document.getElementById('username');
  if (usernameInput) {
    usernameInput.addEventListener('input', onUsernameInput);
  } else {
    console.log('用户名输入框不存在');
  }

  // 案例2：延迟加载大图片或资源
  // 图片加载函数
  function loadImage(): void {
    const img = new Image();
    img.src = 'large-image.jpg';
    img.onload = () => {
      console.log('图片加载完成');
      // 实际应用中，这里可以是将图片添加到DOM的代码
    };
  }

  // 页面加载完成后，1秒后开始加载图片
  window.addEventListener('load', () => {
    const timeoutId: NodeJS.Timeout = setTimeout(loadImage, 1000);
  });

  // 案例3：显示提示信息后自动消失
  // 显示提示信息的函数
  function showHint(message:string, duration:number):undefined | (()=> void) {
    const hintElement = document.getElementById('hint');
    if(!hintElement){
      console.log('提示元素不存在');
      return;
    }
    hintElement.innerText = message;
    hintElement.style.display = 'block';

    // 设置setTimeout，duration毫秒后隐藏提示信息
    const timeoutId:NodeJS.Timeout = setTimeout(() => {
      hintElement.style.display = 'none';
    }, duration);

    // 可以提供清除提示的方法
    return () => clearTimeout(timeoutId);
  }

  // 显示提示信息，并在5秒后自动消失
  const clearHint:(()=> void) | undefined = showHint('操作成功！', 5000);

  // 如果需要提前清除提示，可以调用clearHint();
})()